home *** CD-ROM | disk | FTP | other *** search
- ;
- ; $Id: surf_track.pro,v 1.2 1997/03/26 20:40:21 griz Exp $
- ;
- ; Copyright (c) 1997, Research Systems, Inc. All rights reserved.
- ; Unauthorized reproduction prohibited.
- ;+
- ; NAME:
- ; SURF_TRACK
- ;
- ; PURPOSE:
- ; This procedure serves as an example of using the trackball
- ; object to manipulate a surface object.
- ;
- ; CATEGORY:
- ; Object graphics.
- ;
- ; CALLING SEQUENCE:
- ; SURF_TRACK, [zData]
- ;
- ; OPTIONAL INPUTS:
- ; zData: A two-dimensional floating point array representing
- ; the data to be displayed as a surface. By default,
- ; a BESEL function is displayed.
- ;
- ; MODIFICATION HISTORY:
- ; Written by: DD, June 1996
- ;-
-
- ;----------------------------------------------------------------------------
- FUNCTION Toggle_State, wid
-
- WIDGET_CONTROL, wid, GET_VALUE=name
-
- s = STRPOS(name, '(off)')
- IF (s NE -1) THEN BEGIN
- STRPUT, name, '(on) ', s
- ret = 1
- ENDIF ELSE BEGIN
- s = STRPOS(name, '(on) ')
- STRPUT, name, '(off)',s
- ret = 0
- ENDELSE
-
- WIDGET_CONTROL, wid, SET_VALUE=name
- RETURN, ret
- END
-
- ;----------------------------------------------------------------------------
- PRO SURF_TRACK_EVENT, sEvent
-
- WIDGET_CONTROL, sEvent.id, GET_UVALUE=uval
-
- ; Handle KILL requests.
- IF TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ 'WIDGET_KILL_REQUEST' THEN BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState
-
- ; Destroy the objects.
- OBJ_DESTROY, sState.oHolder
- WIDGET_CONTROL, sEvent.top, /DESTROY
- RETURN
- ENDIF
-
- ; Handle other events.
- CASE uval OF
- 'STYLE': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, STYLE=sEvent.index
- CASE sEvent.index OF
- 0: BEGIN
- WIDGET_CONTROL, sState.wHide, SENSITIVE=1
- WIDGET_CONTROL, sState.wShading, SENSITIVE=0
- END
- 1: BEGIN
- WIDGET_CONTROL, sState.wHide, SENSITIVE=1
- WIDGET_CONTROL, sState.wShading, SENSITIVE=0
- END
- 2: BEGIN
- WIDGET_CONTROL, sState.wHide, SENSITIVE=0
- WIDGET_CONTROL, sState.wShading, SENSITIVE=1
- END
- 3: BEGIN
- WIDGET_CONTROL, sState.wHide, SENSITIVE=1
- WIDGET_CONTROL, sState.wShading, SENSITIVE=0
- END
- 4: BEGIN
- WIDGET_CONTROL, sState.wHide, SENSITIVE=1
- WIDGET_CONTROL, sState.wShading, SENSITIVE=0
- END
- 5: BEGIN
- WIDGET_CONTROL, sState.wHide, SENSITIVE=1
- WIDGET_CONTROL, sState.wShading, SENSITIVE=0
- END
- 6: BEGIN
- WIDGET_CONTROL, sState.wHide, SENSITIVE=0
- WIDGET_CONTROL, sState.wShading, SENSITIVE=1
- END
- ENDCASE
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'MM_MIN0': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, MIN_VALUE=sState.zMinVals[0]
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'MM_MIN1': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, MIN_VALUE=sState.zMinVals[1]
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'MM_MIN2': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, MIN_VALUE=sState.zMinVals[2]
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'MM_MAX0': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, MAX_VALUE=sState.zMaxVals[0]
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'MM_MAX1': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, MAX_VALUE=sState.zMaxVals[1]
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'MM_MAX2': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, MAX_VALUE=sState.zMaxVals[2]
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'SHADE_FLAT': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, SHADING=0
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'SHADE_GOURAUD': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, SHADING=1
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'VC_OFF': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- wParent = WIDGET_INFO(sEvent.id, /PARENT)
- j = Toggle_State(wParent)
- sState.oSurface->SetProperty, VERT_COLORS=0
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'VC_ON': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- wParent = WIDGET_INFO(sEvent.id, /PARENT)
- j = Toggle_State(wParent)
- sState.oSurface->SetProperty, VERT_COLORS=sState.vc
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'HIDE_OFF': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- wParent = WIDGET_INFO(sEvent.id, /PARENT)
- j = Toggle_State(wParent)
- sState.oSurface->SetProperty, HIDDEN_LINES=0
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'HIDE_ON': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- wParent = WIDGET_INFO(sEvent.id, /PARENT)
- j = Toggle_State(wParent)
- sState.oSurface->SetProperty, HIDDEN_LINES=1
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'SKIRT0': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, SHOW_SKIRT=0
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'SKIRT1': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, SKIRT=sState.zSkirts[0], $
- /SHOW_SKIRT
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'SKIRT2': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, SKIRT=sState.zSkirts[1], $
- /SHOW_SKIRT
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'SKIRT3': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.oSurface->SetProperty, SKIRT=sState.zSkirts[2], $
- /SHOW_SKIRT
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'DRAGQ0' : BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.dragq = 0
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'DRAGQ1' : BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
- sState.dragq = 1
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- 'DRAW': BEGIN
- WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
-
- ; Expose.
- IF (sEvent.type EQ 4) THEN BEGIN
- sState.oWindow->Draw, sState.oView
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- RETURN
- ENDIF
-
- ; Handle trackball updates.
- bHaveTransform = sState.oTrack->Update( sEvent, TRANSFORM=qmat )
- IF (bHaveTransform NE 0) THEN BEGIN
- sState.oGroup->GetProperty, TRANSFORM=t
- sState.oGroup->SetProperty, TRANSFORM=t#qmat
- sState.oWindow->Draw, sState.oView
- ENDIF
-
- ; Handle other events: PICKING, quality changes, etc.
- ; Button press.
- IF (sEvent.type EQ 0) THEN BEGIN
- IF (sEvent.press EQ 4) THEN BEGIN ; Right mouse.
- pick = sState.oWindow->PickData(sState.oView,$
- sState.oSurface, $
- [sEvent.x,sEvent.y],dataxyz)
- IF (pick EQ 1) THEN BEGIN
- str = STRING(dataxyz[0],dataxyz[1],dataxyz[2], $
- FORMAT='("Data point: X=",F7.3,",Y=",F7.3,",Z=",F7.3)')
- WIDGET_CONTROL, sState.wLabel, SET_VALUE=str
- ENDIF ELSE BEGIN
- WIDGET_CONTROL, sState.wLabel, $
- SET_VALUE="Data point: In background."
- ENDELSE
-
- sState.btndown = 4b
- WIDGET_CONTROL, sState.wDraw, /DRAW_MOTION
- ENDIF ELSE BEGIN ; other mouse button.
- sState.btndown = 1b
- sState.oWindow->SetProperty, QUALITY=sState.dragq
- WIDGET_CONTROL, sState.wDraw, /DRAW_MOTION
- sState.oWindow->Draw, sState.oView
- ENDELSE
- ENDIF
-
- ; Button motion.
- IF (sEvent.type EQ 2) THEN BEGIN
- IF (sState.btndown EQ 4b) THEN BEGIN ; Right mouse button.
- pick = sState.oWindow->PickData(sState.oView, $
- sState.oSurface, $
- [sEvent.x,sEvent.y], dataxyz)
- IF (pick EQ 1) THEN BEGIN
- str = STRING(dataxyz[0],dataxyz[1],dataxyz[2], $
- FORMAT='("Data point: X=",F7.3,",Y=",F7.3,",Z=",F7.3)')
- WIDGET_CONTROL, sState.wLabel, SET_VALUE=str
- ENDIF ELSE BEGIN
- WIDGET_CONTROL, sState.wLabel, $
- SET_VALUE="Data point: In background."
- ENDELSE
-
- ENDIF
- ENDIF
-
- ; Button release.
- IF (sEvent.type EQ 1) THEN BEGIN
- IF (sState.btndown EQ 1b) THEN BEGIN
- sState.oWindow->SetProperty, QUALITY=2
- sState.oWindow->Draw, sState.oView
- ENDIF
- sState.btndown = 0b
- WIDGET_CONTROL, sState.wDraw, DRAW_MOTION=0
- ENDIF
- WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
- END
- ENDCASE
- END
-
- ;----------------------------------------------------------------------------
- PRO SURF_TRACK, zData
-
- xdim = 480
- ydim = 360
-
- ; Default surface data is a Besel function.
- IF (N_ELEMENTS(zData) EQ 0) THEN $
- zData = BESELJ(SHIFT(DIST(40),20,20)/2,0)
-
- ; Compute potential skirt values.
- zMax = MAX(zData, MIN=zMin)
- zQuart = (zMax - zMin) * 0.25
- zSkirts = [zMin-zQuart, zMin, zMin+zQuart]
-
- ; Create the widgets.
- wBase = WIDGET_BASE(/COLUMN, XPAD=0, YPAD=0, $
- TITLE="Surface Trackball Example", $
- /TLB_KILL_REQUEST_EVENTS)
-
- wDraw = WIDGET_DRAW(wBase, XSIZE=xdim, YSIZE=ydim, UVALUE='DRAW', $
- RETAIN=0, /EXPOSE_EVENTS, /BUTTON_EVENTS, $
- GRAPHICS_LEVEL=2)
- wGuiBase = WIDGET_BASE(wBase, /ROW)
- wStyleDrop = WIDGET_DROPLIST(wGuiBase, VALUE=['Point','Wire','Solid',$
- 'Ruled XZ','Ruled YZ','Lego Wire', $
- 'Lego Solid'], /FRAME, $
- TITLE='Style', UVALUE='STYLE')
-
- wOptions = WIDGET_BUTTON(wGuiBase, MENU=2, VALUE="Additional Options...")
-
- wDrag = WIDGET_BUTTON(wOptions, MENU=2, VALUE="Drag Quality")
- wButton = WIDGET_BUTTON(wDrag, VALUE='Low', UVALUE='DRAGQ0')
- wButton = WIDGET_BUTTON(wDrag, VALUE='Medium', UVALUE='DRAGQ1')
-
- wHide = WIDGET_BUTTON(wOptions, MENU=2, VALUE="Hidden Lines (off)")
- wButton = WIDGET_BUTTON(wHide, VALUE='Off', UVALUE='HIDE_OFF')
- wButton = WIDGET_BUTTON(wHide, VALUE='On', UVALUE='HIDE_ON')
-
- wMinMax = WIDGET_BUTTON(wOptions, MENU=2, VALUE="Minimum")
- zMinVals = [zMin, zMin+zQuart, zMin+2*zQuart]
- zLabels = ['Reset', STRCOMPRESS(STRING(zMinVals[1:2]), /REMOVE_ALL)]
- wButton = WIDGET_BUTTON(wMinMax, VALUE=zLabels[0], UVALUE='MM_MIN0')
- wButton = WIDGET_BUTTON(wMinMax, VALUE=zLabels[1], UVALUE='MM_MIN1')
- wButton = WIDGET_BUTTON(wMinMax, VALUE=zLabels[2], UVALUE='MM_MIN2')
- wMinMax = WIDGET_BUTTON(wOptions, MENU=2, VALUE="Maximum")
- zMaxVals = [zMax, zMax-zQuart, zMax-2*zQuart]
- zLabels = ['Reset', STRCOMPRESS(STRING(zMaxVals[1:2]), /REMOVE_ALL)]
- wButton = WIDGET_BUTTON(wMinMax, VALUE=zLabels[0], UVALUE='MM_MAX0')
- wButton = WIDGET_BUTTON(wMinMax, VALUE=zLabels[1], UVALUE='MM_MAX1')
- wButton = WIDGET_BUTTON(wMinMax, VALUE=zLabels[2], UVALUE='MM_MAX2')
-
- wShading = WIDGET_BUTTON(wOptions, MENU=2, VALUE="Shading")
- wButton = WIDGET_BUTTON(wShading, VALUE='Flat', UVALUE='SHADE_FLAT')
- wButton = WIDGET_BUTTON(wShading, VALUE='Gouraud', UVALUE='SHADE_GOURAUD')
-
- wVC = WIDGET_BUTTON(wOptions, MENU=2, VALUE="Vertex Colors (off)")
- wButton = WIDGET_BUTTON(wVC, VALUE='Off', UVALUE='VC_OFF')
- wButton = WIDGET_BUTTON(wVC, VALUE='On', UVALUE='VC_ON')
-
- zLabels = ['None', STRCOMPRESS(STRING(zSkirts[*]), /REMOVE_ALL)]
- wSkirt = WIDGET_BUTTON(wOptions, MENU=2, VALUE="Skirt")
- wButton = WIDGET_BUTTON(wSkirt, VALUE=zLabels[0], UVALUE='SKIRT0')
- wButton = WIDGET_BUTTON(wSkirt, VALUE=zLabels[1], UVALUE='SKIRT1')
- wButton = WIDGET_BUTTON(wSkirt, VALUE=zLabels[2], UVALUE='SKIRT2')
- wButton = WIDGET_BUTTON(wSkirt, VALUE=zLabels[3], UVALUE='SKIRT3')
-
- ; Status line.
- wGuiBase2 = WIDGET_BASE(wBase, /COLUMN)
- wLabel = WIDGET_LABEL(wGuiBase2, /FRAME, $
- VALUE="Left Mouse: Trackball Right Mouse: Data Picking" )
- wLabel = WIDGET_LABEL(wGuiBase2, VALUE=" ", /DYNAMIC_RESIZE)
-
- WIDGET_CONTROL, wBase, /REALIZE
-
- ; Get the window id of the drawable.
- WIDGET_CONTROL, wDraw, GET_VALUE=oWindow
-
- ; Set default droplist items.
- WIDGET_CONTROL, wStyleDrop, SET_DROPLIST_SELECT=2
- WIDGET_CONTROL, wHide, SENSITIVE=0
-
- ; Compute viewplane rect based on aspect ratio.
- aspect = FLOAT(xdim) / FLOAT(ydim)
- sqrt2 = SQRT(2.0)
- myview = [ -sqrt2*0.5, -sqrt2*0.5, sqrt2, sqrt2 ]
- IF (aspect > 1) THEN BEGIN
- myview[0] = myview[0] - ((aspect-1.0)*myview[2])/2.0
- myview[2] = myview[2] * aspect
- ENDIF ELSE BEGIN
- myview[1] = myview[1] - (((1.0/aspect)-1.0)*myview[3])/2.0
- myview[3] = myview[3] * aspect
- ENDELSE
-
- ; Create view.
- oView = OBJ_NEW('IDLgrView', PROJECTION=2, EYE=3, ZCLIP=[1.4,-1.4],$
- VIEWPLANE_RECT=myview, COLOR=[40,40,40])
-
- ; Create model.
- oTop = OBJ_NEW('IDLgrModel')
- oGroup = OBJ_NEW('IDLgrModel')
- oTop->Add, oGroup
-
- ; Compute data bounds.
- sz = SIZE(zData)
- xMax = sz[1] - 1
- yMax = sz[2] - 1
- zMin2 = zMin - 1
- zMax2 = zMax + 1
-
- ; Compute coordinate conversion to normalize.
- xs = [-0.5,1.0/xMax]
- ys = [-0.5,1.0/yMax]
- zs = [(-zMin2/(zMax2-zMin2))-0.5, 1.0/(zMax2-zMin2)]
-
- ; Generate vertex colors to emulate height fields.
- vc = BYTARR(3,sz[1]*sz[2], /NOZERO)
- cbins=[[255,0,0],$
- [255,85,0],$
- [255,170,0],$
- [255,255,0],$
- [170,255,0],$
- [85,255,0],$
- [0,255,0]]
- zi = ROUND((zData - zMin)/(zMax-zMin) * 6.0)
- vc[*,*] = cbins[*,zi]
-
- ; Create the surface.
- oSurface = OBJ_NEW('IDLgrSurface', zData, STYLE=2, SHADING=0, $
- COLOR=[60,60,255], BOTTOM=[64,192,128], $
- XCOORD_CONV=xs, YCOORD_CONV=ys, ZCOORD_CONV=zs)
- oGroup->Add, oSurface
-
- ; Create some lights.
- oLight = OBJ_NEW('IDLgrLight', LOCATION=[2,2,2], TYPE=1)
- oTop->Add, oLight
- oLight = OBJ_NEW('IDLgrLight', TYPE=0, INTENSITY=0.5)
- oTop->Add, oLight
-
- ; Place the model in the view.
- oView->Add, oTop
-
- ; Rotate to standard view for first draw.
- oGroup->Rotate, [1,0,0], -90
- oGroup->Rotate, [0,1,0], 30
- oGroup->Rotate, [1,0,0], 30
-
- ; Create a trackball.
- oTrack = OBJ_NEW('Trackball', [xdim/2, ydim/2.], xdim/2.)
-
- ; Create a holder object for easy destruction.
- oHolder = OBJ_NEW('IDL_Container')
- oHolder->Add, oView
- oHolder->Add, oTrack
-
- ; Save state.
- sState = {btndown: 0b, $
- dragq: 0, $
- oHolder: oHolder, $
- oTrack:oTrack, $
- wDraw: wDraw, $
- wLabel: wLabel, $
- wHide: wHide, $
- wShading: wShading, $
- oWindow: oWindow, $
- oView: oView, $
- oGroup: oGroup, $
- oSurface: oSurface, $
- zSkirts: zSkirts, $
- zMinVals: zMinVals, $
- zMaxVals: zMaxVals, $
- vc: vc $
- }
-
- WIDGET_CONTROL, wBase, SET_UVALUE=sState, /NO_COPY
-
- XMANAGER, 'SURF_TRACK', wBase, /NO_BLOCK
-
- END
-